package patterns;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class LearnProxy {
    public static void main(String[] args) {
        // JDK的代理类举例，就是在动态生成的实现了原类接口的一个类，不是原类的子类！
        // 1. 得到要代理的对象
        UserServiceImpl userService = new UserServiceImpl();
        // 2. 代理这个对象，传入：类加载器、接口、处理逻辑
        Object proxyInstance = Proxy.newProxyInstance(
                userService.getClass().getClassLoader(),
                userService.getClass().getInterfaces(),
                new UserServiceHandler(userService)
        );
        // 3. 查看这个代理类
        System.out.println("类名：");
        System.out.println(proxyInstance.getClass().getName());
        System.out.println("接口：");
        System.out.println(Arrays.toString(proxyInstance.getClass().getInterfaces()));
        System.out.println("方法：");
        System.out.println(Arrays.toString(proxyInstance.getClass().getMethods()));
        // 4. 使用这个代理示例
        UserService1 proxy1 = (UserService1) proxyInstance;
        UserService2 proxy2 = (UserService2) proxyInstance;
        proxy1.login("123");
        proxy2.buy(123);
    }
}

interface UserService1 {
    void login(String name);
}

interface UserService2 {
    void buy(int amount);
}

// 原类，实现了它的接口
class UserServiceImpl implements UserService1, UserService2 {

    @Override
    public void login(String name) {
        System.out.println("User " + name + " 已登录");
    }

    @Override
    public void buy(int amount) {
        System.out.println("User购买了 " + amount + " 元的商品");
    }
}

// 处理器，用于高速代理类如何处理方法
class UserServiceHandler implements InvocationHandler {

    Object target;

    public UserServiceHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用方法前");
        Object result = method.invoke(target, args);
        System.out.println("调用方法后");
        return result;
    }
}
